// Block-String Functions
// Purpose: To take 2 integer block values and output a string
// containing the Date, Start time and End time of a class.
#include <string>
#include <sstream>

#include "BlockString.h"
using namespace std;


const int maxBlocks = 899; // maximum block number
static int blocksPerDay = (maxBlocks+1)/5; // number of blocks for one day

// Function that converts int to string 
// and fixes the output format for time strings
string timeOutput(int time)
{
	stringstream ss;
	string str;

	if(time/10 == 0){
		ss << 0;
	}
	ss << time;

	ss >> str;
	return str;
}

// Function will output "Hour:Minute" format
// numBlocks is the number of blocks from the beginning of a day
// increment is the time increment (in minutes)
string findTime(int numBlocks, int increment)
{
	int hour = 8; // start hour
	int minute = 0; // start minute
	
	for(int i = 0; i < numBlocks; ++i){
		minute += increment;
		if(minute == 60){
			++hour;
			minute = 0;
		}
	}

	string sHour = timeOutput(hour);
	string sMinute  = timeOutput(minute);

	return (sHour + ":" + sMinute);
}

// Function will output in "Day  Hour:Minute to Hour:Minute" format
// Block 0 = Monday 08:00  -- Block 899 = Friday 22:55
// Error messages:
// 0 - One or both blocks do not conform to limits
// 1 - End block is smaller than start block (class ends before it starts)
// 2 - Blocks indicate different days
string blocksToString(int startBlock, int endBlock)
{
	if(startBlock > maxBlocks || startBlock < 0 || endBlock > maxBlocks || endBlock < 0){ // parameters do not conform to limits
		return "Error 0";
	}
	
	if(endBlock < startBlock){ //class ends before it starts
		return "Error 1";
	}
	
	if((endBlock - startBlock + 1) > blocksPerDay ){ // Day for both blocks differ  
		return "Error 2";
	}


	double day = (startBlock+1)/double(blocksPerDay);
	string result;

	if(day <= 1){ // Monday
		result = "Monday  ";
	}
	else if(day > 1 && day <= 2){ // Tuesday
		result = "Tuesday  ";
	}
	else if(day > 2 && day <= 3){ // Wednesday
		result = "Wednesday  ";
	}
	else if(day > 3 && day <= 4){ // Thursday
		result = "Thursday  ";
	}
	else{ // Friday
		result = "Friday  ";
	}

	int dayBlocks = startBlock % blocksPerDay;
	result += findTime(dayBlocks, 5);

	result += " to ";
	
	dayBlocks = endBlock % blocksPerDay;
    result += findTime(dayBlocks, 5);

	return result;
}

// Function that does a straight conversion from string to integer
int stringToInteger(string str)
{
	stringstream ss;
	int result;
	ss << str;
	ss >> result;

	return result;
}

// Function will take a string containing a time in the format "Day Hour:Minute":
// and output an integer time block
// Error codes
// -1: String is not of the right format 
// -2: Time is invalid
int stringToBlock(string str)
{
    string::size_type space = str.find_first_of(" ");
	string sDay = str.substr(0, space); // day
	string sTime = str.substr(space+1);  // time
	
	int dayVal;
	if(sDay == "Monday"){
		dayVal = 0;
	}
	else if(sDay == "Tuesday"){
		dayVal = 1;
	}
	else if(sDay == "Wednesday"){
		dayVal = 2;
	}
	else if(sDay == "Thursday"){
		dayVal = 3;
	}
	else if (sDay == "Friday"){
		dayVal = 4;
	}
	else{
		return -1; // error
	}

	int result = blocksPerDay * dayVal;

	if(sTime.length() != 5){
		return -1; // error
	}
	
	string sHour = sTime.substr(0,2);
	string sMinute = sTime.substr(3,2);
	int iHour = stringToInteger(sHour);
	int iMinute = stringToInteger(sMinute);

	if(iHour < 8 || iHour >= 23){ //invalid time
		return -2; // error
	}

	int hDiff = iHour - 8;
	int mDiff = iMinute/5;
	
	for(int i = 0; i < hDiff; ++i){
		result += 12;
	}
	for(int j = 0; j < mDiff; ++j){
		++result;
	}

	return result;
}
